/*
 * ExtFieldOT.java
 *
 * $Id: ExtFieldOT.java,v 1.3 2009-09-17 12:11:26 mario Exp $
 *
 * Author: Mario García García - Imagos 2007
 */
package org.ceteca.explica.core.extTables;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Date;

import org.ceteca.explica.core.InterfaceExplica;
import org.ceteca.explica.core.util.DateTime;

/**
 * Store class to hold the data of an extension field. It keeps the metadata and
 * the value of the extension field.
 * <br/>
 * Responsibilities:
 * <li>
 * 	<ul> Store of extension field data for exchanging data among presentation, 
 * business and data access layers. </ul>
 * </li>
 */
public class ExtFieldOT implements Serializable {
	/**
	 * Internal Id of the extension field.
	 */
	private long idExtField;
	/**
	 * Code key of the extension field.
	 */
	private String codExtField;
	/**
	 * Type of the extension field.
	 */
	private Integer fieldType;
	/**
	 * Maximum length (number of characters) of the extension field values.
	 */
	private BigDecimal fieldLength;
	/**
	 * Description of the extension field.
	 */
	private String fieldDescription;
	/**
	 * Value of the id field in the original table (extended table id). It's the 
	 * id value of the extended item.
	 */
	private long idValue;
	/**
	 * Show if the field value can be NULL.
	 */
	private boolean nullable;
	/**
	 * Show if the field value has to be stored in the historic table.
	 */
	private boolean historizable;
	/**
	 * Extension table the extension field is part of.
	 */
	private ExtTableOT extTable;
	
	/**
	 * Value of the extension field for an extended item
	 */
	private Object value;
	
	private static final long serialVersionUID = 10000002;
	
	private Integer version = new Integer(0);
	
	public Integer getVersion() {
		return version;
	}

	public void setVersion(Integer version) {
		this.version = version;
	}
	
	public ExtFieldOT() {
	}
	
	public String getCodExtField() {
		return codExtField;
	}

	public void setCodExtField(String codExtField) {
		this.codExtField = codExtField;
	}

	public BigDecimal getFieldLength() {
		return fieldLength;
	}

	public void setFieldLength(BigDecimal fieldLength) {
		this.fieldLength = fieldLength;
	}

	public Integer getFieldType() {
		return fieldType;
	}
	
	public String getFieldTypeAsString() {
		switch (fieldType) {
			case InterfaceExtTable.EXT_FIELD_TYPE_STRING:
				return "String";
			case InterfaceExtTable.EXT_FIELD_TYPE_DATE:
				return "Date";
			case InterfaceExtTable.EXT_FIELD_TYPE_NUMERIC:
				return "Numeric";
			case InterfaceExtTable.EXT_FIELD_TYPE_BOOLEAN:
				return "Boolean";
			case InterfaceExtTable.EXT_FIELD_TYPE_LONGVALUE:
				return "BLOB";
			default:
				return "NO TYPE";
		}
	}

	public void setFieldType(Integer fieldType) {
		this.fieldType = fieldType;
	}

	public long getIdExtField() {
		return idExtField;
	}

	public void setIdExtField(BigDecimal idExtField) {
		this.idExtField = (idExtField==null)?0:idExtField.longValue();
	}
	
	public void setIdExtField(long idExtField) {
		this.idExtField = idExtField;
	}
	
	public long getIdValue() {
		return idValue;
	}

	public void setIdValue(long idValue) {
		this.idValue = idValue;
	}
	
	public boolean isHistorizable() {
		return historizable;
	}

	public void setHistorizable(boolean historizable) {
		this.historizable = historizable;
	}

	public boolean isNullable() {
		return nullable;
	}

	public void setNullable(boolean nullable) {
		this.nullable = nullable;
	}
	
	public String getFieldDescription() {
		return fieldDescription;
	}

	public void setFieldDescription(String fieldDescription) {
		this.fieldDescription = fieldDescription;
	}
	
	public ExtTableOT getExtTable() {
		return extTable;
	}

	public void setExtTable(ExtTableOT extTable) {
		this.extTable = extTable;
	}

	public boolean equals(Object other) {
        if (this == other) 
        	return true;
        if ( !(other instanceof ExtFieldOT) ) 
        	return false;

        final ExtFieldOT extFld = (ExtFieldOT) other;

        if ( extFld.getCodExtField() == null )
        	return this.getCodExtField() == null;
        else if ( !extFld.getCodExtField().equals( this.getCodExtField() ) ) 
        	return false;

        return true;
    }

    public int hashCode() {
        int result;
        if (this == null || this.getCodExtField() == null)
        	result = 0;
        else
        	result = this.getCodExtField().hashCode();
        return result;
    }
    public String getStrVal() {
    	if (this.fieldType != null && this.fieldType.intValue() == InterfaceExtTable.EXT_FIELD_TYPE_DATE) {
    		DateTime dt = new DateTime((Date)value, InterfaceExplica.CONST_SHORT_DATE_PATTERN);
    		return dt.getDateAsString();
    	}
    	else
    		return value.toString();
    }
    
    public void setStrVal(String value) {
    	if (this.fieldType != null && this.fieldType.intValue() == InterfaceExtTable.EXT_FIELD_TYPE_STRING)
    		this.value = value;
    }
    
    public void setBooVal(Boolean value) {
    	if (this.fieldType != null && this.fieldType.intValue() == InterfaceExtTable.EXT_FIELD_TYPE_BOOLEAN)
    		this.value = value;
    }
    
    public void setNumVal(BigDecimal value) {
    	if (this.fieldType != null && this.fieldType.intValue() == InterfaceExtTable.EXT_FIELD_TYPE_NUMERIC)
    		this.value = value;
    }
    
    public void setDatVal(Date value) {
    	if (this.fieldType != null && this.fieldType.intValue() == InterfaceExtTable.EXT_FIELD_TYPE_DATE)
    		this.value = value;
    }
    
    public void setLonVal(byte[] value) {
    	if (this.fieldType != null && this.fieldType.intValue() == InterfaceExtTable.EXT_FIELD_TYPE_LONGVALUE)
    		this.value = value;
    }
    
    public void setLonVal(String value) {
    	if (this.fieldType != null && this.fieldType.intValue() == InterfaceExtTable.EXT_FIELD_TYPE_LONGVALUE) {
    		BufferedReader in = null; 
    		try {
    			File f = new File(value);
    			if (!f.exists() || !f.canRead()) {
    				this.setLonVal((byte[])null);
    			}
    			else {
    				StringBuffer buf = new StringBuffer();
    				in = new BufferedReader(new FileReader(f));
    		        String str;
    		        while ((str = in.readLine()) != null) {
    		            buf.append(str);
    		        }
    		        this.setLonVal(buf.toString().getBytes());
    			}
		    } catch (Exception ex) {
		    	System.err.println("Abnormal exception caught !: " + ex);
		    	this.setLonVal((byte[])null);
		    } finally {
		    	if (in != null) {
			        try {
			        	in.close();
			        } 
			        catch (IOException ignored) {
			        }
		    	}
		    }
    	}
    }
	
    public Object getValue() {
		return value;
	}

	public void setValue(Object value) {
		this.value = value;
	}
	
	public String getValueAsString() {
		return value != null?this.getStrVal():"";
	}
	
	public void updateValue(String value) {
		if (this.fieldType != null && this.fieldType.intValue() == InterfaceExtTable.EXT_FIELD_TYPE_STRING) {
			this.setStrVal(value);
		}
		else if (this.fieldType != null && this.fieldType.intValue() == InterfaceExtTable.EXT_FIELD_TYPE_DATE) {
			this.setDatVal(new DateTime(value, InterfaceExplica.CONST_SHORT_DATE_PATTERN).getDate());
		}
		else if (this.fieldType != null && this.fieldType.intValue() == InterfaceExtTable.EXT_FIELD_TYPE_BOOLEAN) {
			this.setBooVal(Boolean.parseBoolean(value));
		}
		else if (this.fieldType != null && this.fieldType.intValue() == InterfaceExtTable.EXT_FIELD_TYPE_NUMERIC) {
			this.setNumVal(new BigDecimal(value));
		}
		else if (this.fieldType != null && this.fieldType.intValue() == InterfaceExtTable.EXT_FIELD_TYPE_LONGVALUE) {
			this.setLonVal(value);
		}
	}
	
	/**
	 * Implementation of the toString() method to show the data of the ExtFieldOT
	 * formatted.
	 */
	public String toString() {
		StringBuffer result = new StringBuffer();
		try {
			result.append("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
			result.append("\nID: ");
			result.append(this.idExtField);
			result.append("\nCODE: ");
			result.append(this.codExtField);
			result.append("\nDESCRIPTION: ");
			result.append(this.fieldDescription);
			result.append("\nTYPE: ");
			result.append(this.fieldType);
			result.append("\nLENGTH: ");
			result.append(this.fieldLength);
			result.append("\nNULLABLE?: ");
			result.append(this.nullable);
			result.append("\nHISTORIZABLE?: "); 
			result.append(this.historizable);
			result.append("\nID_VAL: ");
			result.append(this.idValue);
			result.append("\nVALUE: ");
			result.append(this.value);
			result.append("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
		}
		catch (Exception ex) {
			System.out.println("Error formatting ExtensionFieldOT!");
			ex.printStackTrace();
			return null;
		}
		
		return result.toString();
	}
    
	/**
	 * Returns tag Id assigned to CVS source file.
	 */
	public static String getRevision() {
		return "$Id: ExtFieldOT.java,v 1.3 2009-09-17 12:11:26 mario Exp $";
	}
}